package com.xmall.product.define.config;

import com.xmall.msg.queue.ProductModule;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class AmqpPrivateExchangeConfig {

    @Resource
    private RabbitAdmin rabbitAdmin;

    /**
     * 公共直接交换机
     */
    @Bean
    public Exchange stockDirectExchange() {
        DirectExchange exchange = new DirectExchange(ProductModule.CommonExchange.STOCK_DIRECT_EXCHANGE);
        rabbitAdmin.declareExchange(exchange);
        return exchange;
    }

    /**
     * 库存锁定
     * 库存锁定：路由键（product.stock.lock.key） --> 广播交换机（product.stock.lock.fanout.exchange）
     *                                        --> 队列（product.stock.lock.queue）
     */
    @Bean
    public Exchange stockLockFanoutExchange() {
        FanoutExchange exchange = new FanoutExchange(ProductModule.StockLock.STOCK_LOCK_FANOUT_EXCHANGE);
        rabbitAdmin.declareExchange(exchange);
        return exchange;
    }
    @Bean
    public Queue stockLockQueue() {
        Queue queue = new Queue(ProductModule.StockLock.STOCK_LOCK_QUEUE, true, false, false);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }
    @Bean
    public Binding stockLockBinding() {
        Binding binding = BindingBuilder.bind(stockLockQueue()).to(stockLockFanoutExchange()).with(ProductModule.StockLock.STOCK_LOCK_ROUTING_KEY).noargs();
        rabbitAdmin.declareBinding(binding);
        return binding;
    }

    /**
     * 锁定库存检查流向
     * 锁定库存：路由键（product.delay.stock.lock.check.key） --> 直接交换机（product.stock.direct.exchange）
     *                                                    --> 延时队列（product.delay.stock.lock.check.queue）
     * 延时时间到达：路由键（product.stock.lock.check.key）    --> 直接交换机（product.stock.direct.exchange）
     *                                                    --> 队列（product.stock.lock.check.queue）
     */
    @Bean
    public Queue delayStockLockCheckQueue() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-dead-letter-exchange", ProductModule.CommonExchange.STOCK_DIRECT_EXCHANGE);
        args.put("x-dead-letter-routing-key", ProductModule.StockLockCheck.STOCK_LOCK_CHECK_ROUTING_KEY);
        Queue queue = new Queue(ProductModule.StockLockCheck.DELAY_STOCK_LOCK_CHECK_QUEUE, true, false, false, args);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }
    @Bean
    public Binding delayStockLockCheckBinding() {
        Binding binding = BindingBuilder.bind(delayStockLockCheckQueue()).to(stockDirectExchange()).with(ProductModule.StockLockCheck.DELAY_STOCK_LOCK_CHECK_ROUTING_KEY).noargs();
        rabbitAdmin.declareBinding(binding);
        return binding;
    }

    @Bean
    public Queue stockLockCheckQueue() {
        Queue queue = new Queue(ProductModule.StockLockCheck.STOCK_LOCK_CHECK_QUEUE, true, false, false);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }
    @Bean
    public Binding stockLockCheckBinding() {
        Binding binding = BindingBuilder.bind(stockLockCheckQueue()).to(stockDirectExchange()).with(ProductModule.StockLockCheck.STOCK_LOCK_CHECK_ROUTING_KEY).noargs();
        rabbitAdmin.declareBinding(binding);
        return binding;
    }

    /**
     * 库存恢复流向
     * 库存恢复：路由键（product.stock.revert.key） --> 直接交换机（product.stock.direct.exchange）
     *                                          --> 队列（product.stock.revert.queue）
     */
    @Bean
    public Queue stockRevertQueue() {
        Queue queue = new Queue(ProductModule.StockRevert.STOCK_REVERT_QUEUE, true, false, false);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }
    @Bean
    public Binding stockRevertBinding() {
        Binding binding = BindingBuilder.bind(stockRevertQueue()).to(stockDirectExchange()).with(ProductModule.StockRevert.STOCK_REVERT_ROUTING_KEY).noargs();
        rabbitAdmin.declareBinding(binding);
        return binding;
    }

    /**
     * 库存扣减流向
     * 库存扣减：路由键（product.stock.deduct.key） --> 直接交换机（product.stock.direct.exchange）
     *                                          --> 队列（product.stock.deduct.queue）
     */
    @Bean
    public Queue stockDeductQueue() {
        Queue queue = new Queue(ProductModule.StockDeduct.STOCK_DEDUCT_QUEUE, true, false, false);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }
    @Bean
    public Binding stockDeductBinding() {
        Binding binding = BindingBuilder.bind(stockDeductQueue()).to(stockDirectExchange()).with(ProductModule.StockDeduct.STOCK_DEDUCT_ROUTING_KEY).noargs();
        rabbitAdmin.declareBinding(binding);
        return binding;
    }
}
